home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / cagd_lib / cagd_gen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-30  |  22.4 KB  |  724 lines

  1. /******************************************************************************
  2. * Cagd_gen.c - General routines used by all modules of CAGD_lib.          *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Mar. 90.                          *
  5. ******************************************************************************/
  6.  
  7. #include <string.h>
  8. #include "cagd_loc.h"
  9.  
  10. /* Control of the linear order surface convertion to polygon: */
  11. CagdLin2PolyType
  12.     _CagdLin2Poly = CAGD_ONE_POLY_PER_COLIN;
  13.  
  14. static void CagdTransform(CagdRType **Points, int Len, int MaxCoord,
  15.          CagdBType IsNotRational, CagdRType *Translate, CagdRType Scale);
  16. static void CagdMatTransform(CagdRType **Points, int Len, int MaxCoord,
  17.                   CagdBType IsNotRational, CagdMType Mat);
  18.  
  19. /******************************************************************************
  20. * Allocate and reset all slots of a curve structure:                  *
  21. ******************************************************************************/
  22. CagdCrvStruct *CagdCrvNew(CagdGeomType GType, CagdPointType PType, int Length)
  23. {
  24.     int i,
  25.     MaxAxis = CAGD_NUM_OF_PT_COORD(PType);
  26.     CagdCrvStruct
  27.     *NewCrv = (CagdCrvStruct *) IritMalloc(sizeof(CagdCrvStruct));
  28.  
  29.     NewCrv -> GType = GType;
  30.     NewCrv -> PType = PType;
  31.     NewCrv -> Length = Length;
  32.     NewCrv -> Order = 0;
  33.     NewCrv -> KnotVector = NULL;
  34.     NewCrv -> Pnext = NULL;
  35.     NewCrv -> Attr = NULL;
  36.     NewCrv -> Points[0] = NULL;                /* The rational element. */
  37.  
  38.     for (i = !CAGD_IS_RATIONAL_PT(PType); i <= MaxAxis; i++)
  39.     NewCrv -> Points[i] = (CagdRType *) IritMalloc(sizeof(CagdRType) *
  40.                                  Length);
  41.  
  42.     for (i = MaxAxis + 1; i <= CAGD_MAX_PT_COORD; i++)
  43.     NewCrv -> Points[i] = NULL;
  44.  
  45.     return NewCrv;
  46. }
  47.  
  48. /******************************************************************************
  49. * Allocate and reset all slots of a surface structure:                  *
  50. ******************************************************************************/
  51. CagdSrfStruct *CagdSrfNew(CagdGeomType GType, CagdPointType PType, int ULength,
  52.                                    int VLength)
  53. {
  54.     int i,
  55.     MaxAxis = CAGD_NUM_OF_PT_COORD(PType);
  56.     CagdSrfStruct
  57.     *NewSrf = (CagdSrfStruct *) IritMalloc(sizeof(CagdSrfStruct));
  58.  
  59.     NewSrf -> GType = GType;
  60.     NewSrf -> PType = PType;
  61.     NewSrf -> ULength = ULength;
  62.     NewSrf -> VLength = VLength;
  63.     NewSrf -> UOrder = 0;
  64.     NewSrf -> VOrder = 0;
  65.     NewSrf -> UKnotVector = NULL;
  66.     NewSrf -> VKnotVector = NULL;
  67.     NewSrf -> Pnext = NULL;
  68.     NewSrf -> Attr = NULL;
  69.     NewSrf -> Points[0] = NULL;                /* The rational element. */
  70.  
  71.     for (i = !CAGD_IS_RATIONAL_PT(PType); i <= MaxAxis; i++)
  72.     NewSrf -> Points[i] = (CagdRType *) IritMalloc(sizeof(CagdRType) *
  73.                             ULength * VLength);
  74.  
  75.     for (i = MaxAxis + 1; i <= CAGD_MAX_PT_COORD; i++)
  76.     NewSrf -> Points[i] = NULL;
  77.  
  78.     return NewSrf;
  79. }
  80.  
  81. /******************************************************************************
  82. * Allocate and reset all slots of a polygon structure:                  *
  83. ******************************************************************************/
  84. CagdPolygonStruct *CagdPolygonNew(void)
  85. {
  86.     CagdPolygonStruct
  87.     *NewPoly = (CagdPolygonStruct *) IritMalloc(sizeof(CagdPolygonStruct));
  88.  
  89.     NewPoly -> Pnext = NULL;
  90.     NewPoly -> Attr = NULL;
  91.  
  92.     return NewPoly;
  93. }
  94.  
  95.  
  96. /******************************************************************************
  97. * Allocate and reset all slots of a polyline structure:                  *
  98. ******************************************************************************/
  99. CagdPolylineStruct *CagdPolylineNew(int Length)
  100. {
  101.     CagdPolylineStruct
  102.     *NewPoly = (CagdPolylineStruct *) IritMalloc(sizeof(CagdPolylineStruct));
  103.  
  104.     NewPoly -> Pnext = NULL;
  105.     NewPoly -> Attr = NULL;
  106.     NewPoly -> Polyline = (CagdPtStruct *) IritMalloc(sizeof(CagdPtStruct) *
  107.                                        Length);
  108.     NewPoly -> Length = Length;
  109.  
  110.     return NewPoly;
  111. }
  112.  
  113. /******************************************************************************
  114. * Allocate and copy all slots of a curve structure:                  *
  115. ******************************************************************************/
  116. CagdCrvStruct *CagdCrvCopy(CagdCrvStruct *Crv)
  117. {
  118.     int i,
  119.     MaxAxis = CAGD_NUM_OF_PT_COORD(Crv -> PType);
  120.     CagdCrvStruct
  121.     *NewCrv = (CagdCrvStruct *) IritMalloc(sizeof(CagdCrvStruct));
  122.  
  123.     NewCrv -> GType = Crv -> GType;
  124.     NewCrv -> PType = Crv -> PType;
  125.     NewCrv -> Length = Crv -> Length;
  126.     NewCrv -> Order = Crv -> Order;
  127.     if (Crv -> KnotVector != NULL)
  128.     NewCrv -> KnotVector = BspKnotCopy(Crv -> KnotVector,
  129.                        Crv -> Length + Crv -> Order);
  130.     else
  131.     NewCrv -> KnotVector = NULL;
  132.     NewCrv -> Pnext = NULL;
  133.     NewCrv -> Attr = NULL;
  134.     NewCrv -> Points[0] = NULL;                /* The rational element. */
  135.  
  136.     for (i = !CAGD_IS_RATIONAL_PT(Crv -> PType); i <= MaxAxis; i++) {
  137.     NewCrv -> Points[i] = (CagdRType *) IritMalloc(sizeof(CagdRType) *
  138.                                    Crv -> Length);
  139.     CAGD_GEN_COPY(NewCrv -> Points[i], Crv -> Points[i],
  140.               sizeof(CagdRType) * Crv -> Length);
  141.     }
  142.  
  143.     for (i = MaxAxis + 1; i <= CAGD_MAX_PT_COORD; i++)
  144.     NewCrv -> Points[i] = NULL;
  145.  
  146.     return NewCrv;
  147. }
  148.  
  149. /******************************************************************************
  150. * Allocate and copy all slots of a surface structure:                  *
  151. ******************************************************************************/
  152. CagdSrfStruct *CagdSrfCopy(CagdSrfStruct *Srf)
  153. {
  154.     int i,
  155.     MaxAxis = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  156.     CagdSrfStruct
  157.     *NewSrf = (CagdSrfStruct *) IritMalloc(sizeof(CagdSrfStruct));
  158.  
  159.     NewSrf -> GType = Srf -> GType;
  160.     NewSrf -> PType = Srf -> PType;
  161.     NewSrf -> ULength = Srf -> ULength;
  162.     NewSrf -> VLength = Srf -> VLength;
  163.     NewSrf -> UOrder = Srf -> UOrder;
  164.     NewSrf -> VOrder = Srf -> VOrder;
  165.     if (Srf -> UKnotVector != NULL)
  166.     NewSrf -> UKnotVector = BspKnotCopy(Srf -> UKnotVector,
  167.                         Srf -> ULength + Srf -> UOrder);
  168.     else
  169.     NewSrf -> UKnotVector = NULL;
  170.     if (Srf -> VKnotVector != NULL)
  171.     NewSrf -> VKnotVector = BspKnotCopy(Srf -> VKnotVector,
  172.                         Srf -> VLength + Srf -> VOrder);
  173.     else
  174.     NewSrf -> VKnotVector = NULL;
  175.     NewSrf -> Pnext = NULL;
  176.     NewSrf -> Attr = NULL;
  177.     NewSrf -> Points[0] = NULL;                /* The rational element. */
  178.  
  179.     for (i = !CAGD_IS_RATIONAL_PT(Srf -> PType); i <= MaxAxis; i++) {
  180.     NewSrf -> Points[i] = (CagdRType *) IritMalloc(sizeof(CagdRType) *
  181.                      Srf -> ULength * Srf -> VLength);
  182.     CAGD_GEN_COPY(NewSrf -> Points[i], Srf -> Points[i],
  183.               sizeof(CagdRType) * Srf -> ULength * Srf -> VLength);
  184.     }
  185.  
  186.     for (i = MaxAxis + 1; i <= CAGD_MAX_PT_COORD; i++)
  187.     NewSrf -> Points[i] = NULL;
  188.  
  189.     return NewSrf;
  190. }
  191.  
  192. /******************************************************************************
  193. * Allocate and copy all slots of a polygon structure:                  *
  194. ******************************************************************************/
  195. CagdPolygonStruct *CagdPolygonCopy(CagdPolygonStruct *Poly)
  196. {
  197.     CagdPolygonStruct
  198.     *NewPoly = (CagdPolygonStruct *) IritMalloc(sizeof(CagdPolygonStruct));
  199.  
  200.     CAGD_GEN_COPY(NewPoly, Poly, sizeof(CagdPolygonStruct));
  201.     NewPoly -> Pnext = NULL;
  202.     NewPoly -> Attr = NULL;
  203.  
  204.     return NewPoly;
  205. }
  206.  
  207.  
  208. /******************************************************************************
  209. * Allocate and copy all slots of a polyline structure:                  *
  210. ******************************************************************************/
  211. CagdPolylineStruct *CagdPolylineCopy(CagdPolylineStruct *Poly)
  212. {
  213.     CagdPolylineStruct
  214.     *NewPoly = (CagdPolylineStruct *) IritMalloc(sizeof(CagdPolylineStruct));
  215.  
  216.     NewPoly -> Polyline = (CagdPtStruct *) IritMalloc(sizeof(CagdPtStruct) *
  217.                             Poly -> Length);
  218.     CAGD_GEN_COPY(NewPoly -> Polyline, Poly -> Polyline,
  219.                     sizeof(CagdPtStruct) * Poly -> Length);
  220.     NewPoly -> Pnext = NULL;
  221.     NewPoly -> Attr = NULL;
  222.     NewPoly -> Length = Poly -> Length;
  223.  
  224.     return NewPoly;
  225. }
  226.  
  227. /******************************************************************************
  228. * Deallocate and free all slots of a curve structure:                  *
  229. ******************************************************************************/
  230. void CagdCrvFree(CagdCrvStruct *Crv)
  231. {
  232.     int i,
  233.     MaxAxis = CAGD_NUM_OF_PT_COORD(Crv -> PType);
  234.  
  235.     for (i = !CAGD_IS_RATIONAL_CRV(Crv); i <= MaxAxis; i++)
  236.     IritFree((VoidPtr) Crv -> Points[i]);
  237.  
  238.     if (Crv -> KnotVector != NULL)
  239.     IritFree((VoidPtr) Crv -> KnotVector);
  240.  
  241.     AttrFreeAttributes(&Crv -> Attr);
  242.     IritFree((VoidPtr) Crv);
  243. }
  244.  
  245. /******************************************************************************
  246. * Deallocate and free a curve structure list:                      *
  247. ******************************************************************************/
  248. void CagdCrvFreeList(CagdCrvStruct *CrvList)
  249. {
  250.     CagdCrvStruct *CrvTemp;
  251.  
  252.     while (CrvList) {
  253.     CrvTemp = CrvList -> Pnext;
  254.     CagdCrvFree(CrvList);
  255.     CrvList = CrvTemp;
  256.     }
  257. }
  258.  
  259. /******************************************************************************
  260. * Copy a curve structure list:                              *
  261. ******************************************************************************/
  262. CagdCrvStruct *CagdCrvCopyList(CagdCrvStruct *CrvList)
  263. {
  264.     CagdCrvStruct *CrvTemp, *NewCrvList;
  265.  
  266.     if (CrvList == NULL)
  267.     return NULL;
  268.     CrvTemp = NewCrvList = CagdCrvCopy(CrvList);
  269.     CrvList = CrvList -> Pnext;
  270.     while (CrvList) {
  271.     CrvTemp -> Pnext = CagdCrvCopy(CrvList);
  272.     CrvTemp = CrvTemp -> Pnext;
  273.     CrvList = CrvList -> Pnext;
  274.     }
  275.     return NewCrvList;
  276. }
  277.  
  278. /******************************************************************************
  279. * Deallocate and free all slots of a surface structure:                  *
  280. ******************************************************************************/
  281. void CagdSrfFree(CagdSrfStruct *Srf)
  282. {
  283.     int i,
  284.     MaxAxis = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  285.  
  286.     for (i = !CAGD_IS_RATIONAL_SRF(Srf); i <= MaxAxis; i++)
  287.     IritFree((VoidPtr) Srf -> Points[i]);
  288.  
  289.     if (Srf -> UKnotVector != NULL)
  290.     IritFree((VoidPtr) Srf -> UKnotVector);
  291.     if (Srf -> VKnotVector != NULL)
  292.     IritFree((VoidPtr) Srf -> VKnotVector);
  293.  
  294.     AttrFreeAttributes(&Srf -> Attr);
  295.     IritFree((VoidPtr) Srf);
  296. }
  297.  
  298. /******************************************************************************
  299. * Deallocate and free a curve structure list:                      *
  300. ******************************************************************************/
  301. void CagdSrfFreeList(CagdSrfStruct *SrfList)
  302. {
  303.     CagdSrfStruct *SrfTemp;
  304.  
  305.     while (SrfList) {
  306.     SrfTemp = SrfList -> Pnext;
  307.     CagdSrfFree(SrfList);
  308.     SrfList = SrfTemp;
  309.     }
  310. }
  311.  
  312. /******************************************************************************
  313. * Copy a surface structure list:                          *
  314. ******************************************************************************/
  315. CagdSrfStruct *CagdSrfCopyList(CagdSrfStruct *SrfList)
  316. {
  317.     CagdSrfStruct *SrfTemp, *NewSrfList;
  318.  
  319.     if (SrfList == NULL)
  320.     return NULL;
  321.     SrfTemp = NewSrfList = CagdSrfCopy(SrfList);
  322.     SrfList = SrfList -> Pnext;
  323.     while (SrfList) {
  324.     SrfTemp -> Pnext = CagdSrfCopy(SrfList);
  325.     SrfTemp = SrfTemp -> Pnext;
  326.     SrfList = SrfList -> Pnext;
  327.     }
  328.     return NewSrfList;
  329. }
  330.  
  331. /******************************************************************************
  332. * Deallocate and free a curve structure list:                      *
  333. ******************************************************************************/
  334. void CagdPolylineFree(CagdPolylineStruct *Poly)
  335. {
  336.     IritFree((VoidPtr) Poly -> Polyline);
  337.     AttrFreeAttributes(&Poly -> Attr);
  338.     IritFree((VoidPtr) Poly);
  339. }
  340.  
  341. /******************************************************************************
  342. * Deallocate and free a curve structure list:                      *
  343. ******************************************************************************/
  344. void CagdPolylineFreeList(CagdPolylineStruct *PolyList)
  345. {
  346.     CagdPolylineStruct *PolyTemp;
  347.  
  348.     while (PolyList) {
  349.     PolyTemp = PolyList -> Pnext;
  350.     CagdPolylineFree(PolyList);
  351.     PolyList = PolyTemp;
  352.     }
  353. }
  354.  
  355. /******************************************************************************
  356. * Copy a polyline structure list:                          *
  357. ******************************************************************************/
  358. CagdPolylineStruct *CagdPolylineCopyList(CagdPolylineStruct *PolyList)
  359. {
  360.     CagdPolylineStruct *PolyTemp, *NewPolyList;
  361.  
  362.     if (PolyList == NULL)
  363.     return NULL;
  364.     PolyTemp = NewPolyList = CagdPolylineCopy(PolyList);
  365.     PolyList = PolyList -> Pnext;
  366.     while (PolyList) {
  367.     PolyTemp -> Pnext = CagdPolylineCopy(PolyList);
  368.     PolyTemp = PolyTemp -> Pnext;
  369.     PolyList = PolyList -> Pnext;
  370.     }
  371.     return NewPolyList;
  372. }
  373.  
  374. /******************************************************************************
  375. * Deallocate and free a curve structure list:                      *
  376. ******************************************************************************/
  377. void CagdPolygonFree(CagdPolygonStruct *Poly)
  378. {
  379.     AttrFreeAttributes(&Poly -> Attr);
  380.     IritFree((VoidPtr) Poly);
  381. }
  382.  
  383. /******************************************************************************
  384. * Deallocate and free a curve structure list:                      *
  385. ******************************************************************************/
  386. void CagdPolygonFreeList(CagdPolygonStruct *PolyList)
  387. {
  388.     CagdPolygonStruct *PolyTemp;
  389.  
  390.     while (PolyList) {
  391.     PolyTemp = PolyList -> Pnext;
  392.     CagdPolygonFree(PolyList);
  393.     PolyList = PolyTemp;
  394.     }
  395. }
  396.  
  397. /******************************************************************************
  398. * Copy a polygon structure list:                          *
  399. ******************************************************************************/
  400. CagdPolygonStruct *CagdPolygonCopyList(CagdPolygonStruct *PolyList)
  401. {
  402.     CagdPolygonStruct *PolyTemp, *NewPolyList;
  403.  
  404.     if (PolyList == NULL)
  405.     return NULL;
  406.     PolyTemp = NewPolyList = CagdPolygonCopy(PolyList);
  407.     PolyList = PolyList -> Pnext;
  408.     while (PolyList) {
  409.     PolyTemp -> Pnext = CagdPolygonCopy(PolyList);
  410.     PolyTemp = PolyTemp -> Pnext;
  411.     PolyList = PolyList -> Pnext;
  412.     }
  413.     return NewPolyList;
  414. }
  415.  
  416. /******************************************************************************
  417. * Deallocate and free a point structure list:                      *
  418. ******************************************************************************/
  419. void CagdPtFreeList(CagdPtStruct *PtList)
  420. {
  421.     CagdPtStruct *PtTemp;
  422.  
  423.     while (PtList) {
  424.     PtTemp = PtList -> Pnext;
  425.     IritFree((VoidPtr) PtList);
  426.     PtList = PtTemp;
  427.     }
  428. }
  429.  
  430. /******************************************************************************
  431. * Deallocate and free a control point structure list:                  *
  432. ******************************************************************************/
  433. void CagdCtlPtFreeList(CagdCtlPtStruct *CtlPtList)
  434. {
  435.     CagdCtlPtStruct *CtlPtTemp;
  436.  
  437.     while (CtlPtList) {
  438.     CtlPtTemp = CtlPtList -> Pnext;
  439.     IritFree((VoidPtr) CtlPtList);
  440.     CtlPtList = CtlPtTemp;
  441.     }
  442. }
  443.  
  444. /******************************************************************************
  445. * Deallocate and free a vector structure list:                      *
  446. ******************************************************************************/
  447. void CagdVecFreeList(CagdVecStruct *VecList)
  448. {
  449.     CagdVecStruct *VecTemp;
  450.  
  451.     while (VecList) {
  452.     VecTemp = VecList -> Pnext;
  453.     IritFree((VoidPtr) VecList);
  454.     VecList = VecTemp;
  455.     }
  456. }
  457.  
  458. /******************************************************************************
  459. * Deallocate and free a plane point structure list:                  *
  460. ******************************************************************************/
  461. void CagdPlaneFreeList(CagdPlaneStruct *PlaneList)
  462. {
  463.     CagdPlaneStruct *PlaneTemp;
  464.  
  465.     while (PlaneList) {
  466.     PlaneTemp = PlaneList -> Pnext;
  467.     IritFree((VoidPtr) PlaneList);
  468.     PlaneList = PlaneTemp;
  469.     }
  470. }
  471.  
  472. /******************************************************************************
  473. * Deallocate and free a bound box structure list:                  *
  474. ******************************************************************************/
  475. void CagdBBoxFreeList(CagdBBoxStruct *BBoxList)
  476. {
  477.     CagdBBoxStruct *BBoxTemp;
  478.  
  479.     while (BBoxList) {
  480.     BBoxTemp = BBoxList -> Pnext;
  481.  
  482.     IritFree((VoidPtr) BBoxList);
  483.     BBoxList = BBoxTemp;
  484.     }
  485. }
  486.  
  487. /******************************************************************************
  488. * Reverse a list of objects, in place.                          *
  489. ******************************************************************************/
  490. VoidPtr CagdListReverse(VoidPtr List)
  491. {
  492.     CagdGenericStruct
  493.     *OldHead = (CagdGenericStruct *) List,
  494.     *NewHead = NULL;
  495.  
  496.     while (OldHead) {
  497.     CagdGenericStruct
  498.         *TmpStruct = OldHead -> Pnext;
  499.  
  500.     OldHead -> Pnext = NewHead;
  501.     NewHead = OldHead;
  502.  
  503.     OldHead = TmpStruct;
  504.     }
  505.  
  506.     return (VoidPtr) NewHead;
  507. }
  508.  
  509. /******************************************************************************
  510. * Linear transform in place given Crv as specified by Translate and Scale.    *
  511. ******************************************************************************/
  512. void CagdCrvTransform(CagdCrvStruct *Crv, CagdRType *Translate,
  513.                                  CagdRType Scale)
  514. {
  515.     switch (Crv -> GType) {
  516.     case CAGD_CBEZIER_TYPE:
  517.     case CAGD_CBSPLINE_TYPE:
  518.             CagdTransform(Crv -> Points,
  519.               Crv -> Length,
  520.                   CAGD_NUM_OF_PT_COORD(Crv -> PType),
  521.                   !CAGD_IS_RATIONAL_CRV(Crv),
  522.               Translate,
  523.               Scale);
  524.  
  525.         break;
  526.     case CAGD_CPOWER_TYPE:
  527.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  528.         break;
  529.     default:
  530.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  531.         break;
  532.     }
  533. }
  534.  
  535. /******************************************************************************
  536. * Linear transform in place given Srf as specified by Translate and Scale.    *
  537. ******************************************************************************/
  538. void CagdSrfTransform(CagdSrfStruct *Srf, CagdRType *Translate,
  539.                                  CagdRType Scale)
  540. {
  541.     switch (Srf -> GType) {
  542.     case CAGD_SBEZIER_TYPE:
  543.     case CAGD_SBSPLINE_TYPE:
  544.         CagdTransform(Srf -> Points,
  545.                   Srf -> ULength * Srf -> VLength,
  546.                       CAGD_NUM_OF_PT_COORD(Srf -> PType),
  547.               !CAGD_IS_RATIONAL_SRF(Srf),
  548.                   Translate,
  549.                       Scale);
  550.         break;
  551.     case CAGD_SPOWER_TYPE:
  552.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  553.         break;
  554.     default:
  555.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  556.         break;
  557.     }
  558. }
  559.  
  560. /******************************************************************************
  561. * Linear transform in place given Data as specified by Translate and Scale.   *
  562. ******************************************************************************/
  563. static void CagdTransform(CagdRType **Points, int Len, int MaxCoord,
  564.          CagdBType IsNotRational, CagdRType *Translate, CagdRType Scale)
  565. {
  566.     int i, j;
  567.  
  568.     if (IsNotRational)
  569.     for (i = 1; i <= MaxCoord; i++)
  570.         for (j = 0; j < Len; j++)
  571.         Points[i][j] = (Points[i][j] + Translate[i - 1]) * Scale;
  572.     else
  573.     for (i = 1; i <= MaxCoord; i++)
  574.         for (j = 0; j < Len; j++)
  575.         Points[i][j] = (Points[i][j] +
  576.                 Translate[i - 1] * Points[W][j]) * Scale;
  577. }
  578.  
  579. /******************************************************************************
  580. * Linear transform in place the given Crv as specified by Mat.              *
  581. ******************************************************************************/
  582. void CagdCrvMatTransform(CagdCrvStruct *Crv, CagdMType Mat)
  583. {
  584.     switch (Crv -> GType) {
  585.     case CAGD_CBEZIER_TYPE:
  586.     case CAGD_CBSPLINE_TYPE:
  587.         CagdMatTransform(Crv -> Points,
  588.                      Crv -> Length,
  589.                          CAGD_NUM_OF_PT_COORD(Crv -> PType),
  590.                  !CAGD_IS_RATIONAL_CRV(Crv),
  591.                      Mat);
  592.         break;
  593.     case CAGD_CPOWER_TYPE:
  594.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  595.         break;
  596.     default:
  597.         FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
  598.         break;
  599.     }
  600. }
  601.  
  602. /******************************************************************************
  603. * Linear transform in place the given Srf as specified by Mat.              *
  604. ******************************************************************************/
  605. void CagdSrfMatTransform(CagdSrfStruct *Srf, CagdMType Mat)
  606. {
  607.     switch (Srf -> GType) {
  608.     case CAGD_SBEZIER_TYPE:
  609.     case CAGD_SBSPLINE_TYPE:
  610.         CagdMatTransform(Srf -> Points,
  611.                      Srf -> ULength * Srf -> VLength,
  612.                          CAGD_NUM_OF_PT_COORD(Srf -> PType),
  613.                  !CAGD_IS_RATIONAL_SRF(Srf),
  614.                      Mat);
  615.         break;
  616.     case CAGD_SPOWER_TYPE:
  617.         FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
  618.         break;
  619.     default:
  620.         FATAL_ERROR(CAGD_ERR_UNDEF_SRF);
  621.         break;
  622.     }
  623. }
  624.  
  625. /******************************************************************************
  626. * Linear transform in place the given Data as specified by Mat.              *
  627. ******************************************************************************/
  628. static void CagdMatTransform(CagdRType **Points, int Len, int MaxCoord,
  629.                   CagdBType IsNotRational, CagdMType Mat)
  630. {
  631.     int i, j;
  632.     CagdRType P[4], Q[4];
  633.  
  634.     if (MaxCoord > 3)
  635.     MaxCoord = 3;
  636.  
  637.     if (IsNotRational)
  638.     for (i = 0; i < Len; i++) {
  639.         for (j = 1; j <= MaxCoord; j++)
  640.         P[j - 1] = Points[j][i];
  641.  
  642.         /* Zero unused coords. */
  643.         for (j = MaxCoord + 1; j < 3; i++)
  644.         P[j - 1] = 0.0;
  645.  
  646.             MatMultVecby4by4(Q, P, Mat);
  647.  
  648.         for (j = 1; j <= MaxCoord; j++)
  649.         Points[j][i] = Q[j - 1];
  650.         }
  651.     else
  652.     for (i = 0; i < Len; i++) {
  653.         for (j = 1; j <= MaxCoord; j++)
  654.         P[j - 1] = Points[j][i];
  655.         P[3] = Points[W][i];
  656.  
  657.         /* Zero unused coords. */
  658.         for (j = MaxCoord + 1; j < 3; i++)
  659.         P[j - 1] = 0.0;
  660.  
  661.             MatMultWVecby4by4(Q, P, Mat);
  662.  
  663.         for (j = 1; j <= MaxCoord; j++)
  664.         Points[j][i] = Q[j - 1];
  665.         Points[W][i] = Q[3];
  666.         }
  667. }
  668.  
  669. /*****************************************************************************
  670. * Routine to create one polygon given its vertices.                 *
  671. *****************************************************************************/
  672. CagdPolygonStruct *_CagdMakePolygon(CagdBType ComputeNormals,
  673.                     CagdBType ComputeUV,
  674.                     CagdPtStruct *Pt1,
  675.                     CagdPtStruct *Pt2,
  676.                     CagdPtStruct *Pt3,
  677.                     CagdVecStruct *Nl1,
  678.                     CagdVecStruct *Nl2,
  679.                     CagdVecStruct *Nl3,
  680.                     CagdUVStruct *UV1,
  681.                     CagdUVStruct *UV2,
  682.                     CagdUVStruct *UV3)
  683. {
  684.     CagdPolygonStruct
  685.     *Poly = CagdPolygonNew();
  686.  
  687.     CAGD_COPY_POINT(Poly -> Polygon[0], *Pt1);
  688.     CAGD_COPY_POINT(Poly -> Polygon[1], *Pt2);
  689.     CAGD_COPY_POINT(Poly -> Polygon[2], *Pt3);
  690.  
  691.     if (ComputeNormals) {
  692.     CAGD_COPY_VECTOR(Poly -> Normal[0], *Nl1);
  693.     CAGD_COPY_VECTOR(Poly -> Normal[1], *Nl2);
  694.     CAGD_COPY_VECTOR(Poly -> Normal[2], *Nl3);
  695.     }
  696.     else {
  697.     CAGD_RESET_VECTOR(Poly -> Normal[0]);
  698.     CAGD_RESET_VECTOR(Poly -> Normal[1]);
  699.     CAGD_RESET_VECTOR(Poly -> Normal[2]);
  700.     }
  701.  
  702.     if (ComputeUV) {
  703.     CAGD_COPY_UVVAL(Poly -> UV[0], *UV1);
  704.     CAGD_COPY_UVVAL(Poly -> UV[1], *UV2);
  705.     CAGD_COPY_UVVAL(Poly -> UV[2], *UV3);
  706.     }
  707.     else {
  708.     CAGD_RESET_UVVAL(Poly -> UV[0]);
  709.     CAGD_RESET_UVVAL(Poly -> UV[1]);
  710.     CAGD_RESET_UVVAL(Poly -> UV[2]);
  711.     }
  712.  
  713.     return Poly;
  714. }
  715.  
  716. /*****************************************************************************
  717. * Set the way (co)linear surfaces are converted into polygons.             *
  718. *****************************************************************************/
  719. void CagdSetLinear2Poly(CagdLin2PolyType Lin2Poly)
  720. {
  721.     _CagdLin2Poly = Lin2Poly;
  722. }
  723.  
  724.